using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ComponentSystem;
using UnityEngine;

namespace UnityActionSystem.Samples
{
    /// <summary>
    /// 压力测试类型枚举
    /// </summary>
    public enum StressTestType
    {
        All,                    // 所有测试
        Throughput,            // 吞吐量测试
        QueueBacklog,          // 队列积压测试
        PriorityMixed,         // 多优先级混合测试
        ContinuousStress,      // 持续压力测试
        ConcurrentSubscribers  // 并发订阅测试
    }

    /// <summary>
    /// 性能监控工具类
    /// </summary>
    public class PerformanceMonitor
    {
        public float StartTime;
        public int EventsPublished;
        public int EventsProcessed;
        public int GCCountBefore;
        public int GCCountAfter;
        public long MemoryBefore;
        public long MemoryAfter;

        public void Start()
        {
            StartTime = Time.realtimeSinceStartup;
            GCCountBefore = System.GC.CollectionCount(0);
            MemoryBefore = System.GC.GetTotalMemory(false);
        }

        public void End()
        {
            GCCountAfter = System.GC.CollectionCount(0);
            MemoryAfter = System.GC.GetTotalMemory(false);
        }

        public void PrintResults()
        {
            float duration = Time.realtimeSinceStartup - StartTime;
            float throughput = EventsProcessed / duration;
            int gcCount = GCCountAfter - GCCountBefore;
            long memoryDelta = MemoryAfter - MemoryBefore;

            Debug.Log($"=== 性能报告 ===");
            Debug.Log($"总耗时: {duration:F3}秒");
            Debug.Log($"发布事件: {EventsPublished}");
            Debug.Log($"处理事件: {EventsProcessed}");
            Debug.Log($"吞吐量: {throughput:F1} 事件/秒");
            Debug.Log($"GC次数: {gcCount}");
            Debug.Log($"内存变化: {memoryDelta / 1024f:F2} KB");
            Debug.Log($"平均延迟: {(duration / EventsProcessed * 1000):F2} ms");
        }
    }

    /// <summary>
    /// 事件系统测试器
    /// 自动运行各种测试用例，在控制台输出测试结果
    /// </summary>
    public class EventSystemTester : MonoBehaviour
    {
        [Header("压力测试配置")]
        [SerializeField] private bool enableStressTest = false;
        [SerializeField] private StressTestType testType = StressTestType.All;

        private EventBusEntity _eventBus;
        private int _testResults = 0;
        private int _totalTests = 0;

        private void Start()
        {
            Debug.Log("=== 事件系统测试开始 ===");
            StartCoroutine(RunAllTests());
        }

        /// <summary>
        /// 运行所有测试
        /// </summary>
        private IEnumerator RunAllTests()
        {
            // 初始化EventBus
            _eventBus = ComponentFactory.CreateEntityCSharp<EventBusEntity>();
            _eventBus.Initialization();
            Debug.Log("✓ EventBus初始化成功");

            // 等待一帧确保EventBus完全初始化
            yield return null;

            // 运行基础功能测试
            yield return StartCoroutine(TestBasicFunctions());

            // 运行优先级测试
            yield return StartCoroutine(TestPrioritySystem());

            // 运行队列管理测试
            yield return StartCoroutine(TestQueueManagement());

            // 运行监听器管理测试
            yield return StartCoroutine(TestListenerManagement());

            // 运行压力测试
            yield return StartCoroutine(RunStressTests());

            // 输出测试结果
            Debug.Log($"=== 测试完成 ===");
            Debug.Log($"总测试数: {_totalTests}");
            Debug.Log($"通过测试: {_testResults}");
            Debug.Log($"失败测试: {_totalTests - _testResults}");
            Debug.Log($"成功率: {(_testResults * 100f / _totalTests):F1}%");
        }

        /// <summary>
        /// 测试基础功能
        /// </summary>
        private IEnumerator TestBasicFunctions()
        {
            Debug.Log("\n--- 基础功能测试 ---");

            // 测试1: 订阅和发布立即事件
            _totalTests++;
            bool immediateTestPassed = false;

            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestMessage, (data) =>
            {
                immediateTestPassed = true;
                Debug.Log($"✓ 收到消息: {data.Message} (类型: {data.MessageType})");
            });

            _eventBus.Publish(TestEventIds.TestMessage, new TestMessageEvent("测试消息", "Test"), EventPriority.Immediate);

            if (immediateTestPassed)
            {
                _testResults++;
                Debug.Log("✓ 测试1通过: 立即事件订阅和发布");
            }
            else
            {
                Debug.LogError("✗ 测试1失败: 立即事件订阅和发布");
            }

            yield return null;

            // 测试2: 多个监听器
            _totalTests++;
            int listenerCount = 0;

            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestMessage, (data) => listenerCount++);
            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestMessage, (data) => listenerCount++);

            _eventBus.Publish(TestEventIds.TestMessage, new TestMessageEvent("多监听器测试"), EventPriority.Immediate);

            if (listenerCount >= 2)
            {
                _testResults++;
                Debug.Log($"✓ 测试2通过: 多个监听器 (收到{listenerCount}次)");
            }
            else
            {
                Debug.LogError($"✗ 测试2失败: 多个监听器 (只收到{listenerCount}次)");
            }

            yield return null;

            // 测试3: 取消订阅
            _totalTests++;
            int unsubscribeTestCount = 0;

            EventBusEntity.EventHandler<TestMessageEvent> handler = (data) => unsubscribeTestCount++;
            _eventBus.Subscribe(TestEventIds.TestMessage, handler);
            _eventBus.Unsubscribe(TestEventIds.TestMessage, handler);

            _eventBus.Publish(TestEventIds.TestMessage, new TestMessageEvent("取消订阅测试"), EventPriority.Immediate);

            if (unsubscribeTestCount == 0)
            {
                _testResults++;
                Debug.Log("✓ 测试3通过: 取消订阅");
            }
            else
            {
                Debug.LogError($"✗ 测试3失败: 取消订阅 (仍收到{unsubscribeTestCount}次)");
            }
        }

        /// <summary>
        /// 测试优先级系统
        /// </summary>
        private IEnumerator TestPrioritySystem()
        {
            Debug.Log("\n--- 优先级系统测试 ---");

            // 测试4: 高优先级事件（下一帧执行）
            _totalTests++;
            bool highPriorityExecuted = false;

            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestPriority, (data) =>
            {
                highPriorityExecuted = true;
                Debug.Log($"✓ 高优先级事件执行: {data.Message}");
            });

            _eventBus.Publish(TestEventIds.TestPriority, new TestMessageEvent("高优先级测试"), EventPriority.High);

            // 检查当前帧是否未执行
            if (!highPriorityExecuted)
            {
                Debug.Log("✓ 高优先级事件未在当前帧执行（正确）");
            }
            else
            {
                Debug.LogError("✗ 高优先级事件在当前帧执行了（错误）");
            }

            yield return null; // 等待下一帧

            // 检查下一帧是否执行
            if (highPriorityExecuted)
            {
                _testResults++;
                Debug.Log("✓ 测试4通过: 高优先级事件在下一帧执行");
            }
            else
            {
                Debug.LogError("✗ 测试4失败: 高优先级事件未在下一帧执行");
            }

            // 测试5: 普通优先级事件（队列处理）
            _totalTests++;
            bool normalPriorityExecuted = false;

            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestPriority, (data) =>
            {
                normalPriorityExecuted = true;
                Debug.Log($"✓ 普通优先级事件执行: {data.Message}");
            });

            _eventBus.Publish(TestEventIds.TestPriority, new TestMessageEvent("普通优先级测试"), EventPriority.Normal);

            // 检查当前帧是否未执行
            if (!normalPriorityExecuted)
            {
                Debug.Log("✓ 普通优先级事件未在当前帧执行（正确）");
            }

            yield return null; // 等待队列处理

            // 检查下一帧是否执行
            if (normalPriorityExecuted)
            {
                _testResults++;
                Debug.Log("✓ 测试5通过: 普通优先级事件通过队列处理");
            }
            else
            {
                Debug.LogError("✗ 测试5失败: 普通优先级事件未通过队列处理");
            }
        }

        /// <summary>
        /// 测试队列管理
        /// </summary>
        private IEnumerator TestQueueManagement()
        {
            Debug.Log("\n--- 队列管理测试 ---");

            // 测试6: 队列状态查询
            _totalTests++;

            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestQueue, (data) =>
            {
                Debug.Log($"✓ 队列事件执行: {data.Message}");
            });

            // 发布多个普通优先级事件
            for (int i = 0; i < 5; i++)
            {
                _eventBus.Publish(TestEventIds.TestQueue, new TestMessageEvent($"队列测试 {i + 1}"), EventPriority.Normal);
            }

            int queueCount = _eventBus.GetQueueCount();
            if (queueCount == 5)
            {
                _testResults++;
                Debug.Log($"✓ 测试6通过: 队列状态查询 (队列中有{queueCount}个事件)");
            }
            else
            {
                Debug.LogError($"✗ 测试6失败: 队列状态查询 (期望5个，实际{queueCount}个)");
            }

            yield return null; // 等待队列处理

            // 测试7: 清空队列
            _totalTests++;

            // 再次添加事件到队列
            _eventBus.Publish(TestEventIds.TestQueue, new TestMessageEvent("清空测试"), EventPriority.Normal);

            int beforeClear = _eventBus.GetQueueCount();
            _eventBus.ClearEventQueue();
            int afterClear = _eventBus.GetQueueCount();

            if (beforeClear > 0 && afterClear == 0)
            {
                _testResults++;
                Debug.Log("✓ 测试7通过: 清空事件队列");
            }
            else
            {
                Debug.LogError($"✗ 测试7失败: 清空事件队列 (清空前:{beforeClear}, 清空后:{afterClear})");
            }
        }

        /// <summary>
        /// 测试监听器管理
        /// </summary>
        private IEnumerator TestListenerManagement()
        {
            Debug.Log("\n--- 监听器管理测试 ---");

            // 测试8: 获取监听器数量
            _totalTests++;

            int initialCount = _eventBus.GetListenerCount(TestEventIds.TestListener);

            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestListener, (data) => { });
            _eventBus.Subscribe<TestMessageEvent>(TestEventIds.TestListener, (data) => { });

            int afterSubscribe = _eventBus.GetListenerCount(TestEventIds.TestListener);

            if (afterSubscribe == initialCount + 2)
            {
                _testResults++;
                Debug.Log($"✓ 测试8通过: 获取监听器数量 (订阅后:{afterSubscribe}个)");
            }
            else
            {
                Debug.LogError($"✗ 测试8失败: 获取监听器数量 (期望:{initialCount + 2}, 实际:{afterSubscribe})");
            }

            yield return null;

            // 测试9: 清空所有监听器
            _totalTests++;

            _eventBus.ClearAllListeners();
            int afterClear = _eventBus.GetListenerCount(TestEventIds.TestListener);

            if (afterClear == 0)
            {
                _testResults++;
                Debug.Log("✓ 测试9通过: 清空所有监听器");
            }
            else
            {
                Debug.LogError($"✗ 测试9失败: 清空所有监听器 (剩余:{afterClear}个)");
            }
        }

        #region 压力测试方法

        /// <summary>
        /// 运行压力测试
        /// </summary>
        private IEnumerator RunStressTests()
        {
            if (!enableStressTest)
                yield break;

            Debug.Log("\n========== 压力测试开始 ==========");

            switch (testType)
            {
                case StressTestType.All:
                    yield return TestThroughput();
                    yield return new WaitForSeconds(1f);
                    yield return TestQueueBacklog();
                    yield return new WaitForSeconds(1f);
                    yield return TestPriorityMixed();
                    yield return new WaitForSeconds(1f);
                    yield return TestContinuousStress();
                    yield return new WaitForSeconds(1f);
                    yield return TestConcurrentSubscribers();
                    break;

                case StressTestType.Throughput:
                    yield return TestThroughput();
                    break;

                case StressTestType.QueueBacklog:
                    yield return TestQueueBacklog();
                    break;

                case StressTestType.PriorityMixed:
                    yield return TestPriorityMixed();
                    break;

                case StressTestType.ContinuousStress:
                    yield return TestContinuousStress();
                    break;

                case StressTestType.ConcurrentSubscribers:
                    yield return TestConcurrentSubscribers();
                    break;
            }

            Debug.Log("\n========== 压力测试完成 ==========");
        }

        /// <summary>
        /// 吞吐量测试
        /// </summary>
        private IEnumerator TestThroughput()
        {
            Debug.Log("\n=== 吞吐量测试 ===");
            var monitor = new PerformanceMonitor();
            int eventCount = 1000;
            int processedCount = 0;

            // 订阅事件
            EventBusEntity.EventHandler<TestMessageEvent> handler = (data) => processedCount++;
            _eventBus.Subscribe(TestEventIds.TestMessage, handler);

            monitor.Start();
            monitor.EventsPublished = eventCount;

            // 快速发布1000个事件
            for (int i = 0; i < eventCount; i++)
            {
                EventPriority priority = (EventPriority)(i % 3 + 1); // High, Normal, Low
                _eventBus.Publish(
                    TestEventIds.TestMessage,
                    new TestMessageEvent($"Throughput Test {i}"),
                    priority
                );
            }

            // 等待所有事件处理完成
            yield return new WaitForSeconds(2f);

            monitor.EventsProcessed = processedCount;
            monitor.End();
            monitor.PrintResults();

            _eventBus.Unsubscribe(TestEventIds.TestMessage, handler);
        }

        /// <summary>
        /// 队列积压测试
        /// </summary>
        private IEnumerator TestQueueBacklog()
        {
            Debug.Log("\n=== 队列积压测试 ===");
            var monitor = new PerformanceMonitor();
            int eventCount = 5000;
            int processedCount = 0;

            EventBusEntity.EventHandler<TestMessageEvent> handler = (data) => processedCount++;
            _eventBus.Subscribe(TestEventIds.TestMessage, handler);

            monitor.Start();
            monitor.EventsPublished = eventCount;

            // 快速发布5000个事件，制造积压
            for (int i = 0; i < eventCount; i++)
            {
                _eventBus.Publish(
                    TestEventIds.TestMessage,
                    new TestMessageEvent($"Backlog Test {i}"),
                    EventPriority.Normal
                );
            }

            Debug.Log($"初始队列长度: {_eventBus.GetQueueCount()}");

            // 监控队列消化过程
            float startTime = Time.time;
            while (_eventBus.GetQueueCount() > 0 && Time.time - startTime < 10f)
            {
                Debug.Log($"队列剩余: {_eventBus.GetQueueCount()}");
                yield return new WaitForSeconds(0.5f);
            }

            monitor.EventsProcessed = processedCount;
            monitor.End();
            monitor.PrintResults();

            _eventBus.Unsubscribe(TestEventIds.TestMessage, handler);
        }

        /// <summary>
        /// 多优先级混合测试
        /// </summary>
        private IEnumerator TestPriorityMixed()
        {
            Debug.Log("\n=== 多优先级混合测试 ===");

            var highCount = 0;
            var normalCount = 0;
            var lowCount = 0;
            var executionOrder = new List<string>();

            // 订阅三种不同的事件类型
            EventBusEntity.EventHandler<TestMessageEvent> highHandler = (data) =>
            {
                highCount++;
                executionOrder.Add($"H{highCount}");
            };

            EventBusEntity.EventHandler<TestPlayerEvent> normalHandler = (data) =>
            {
                normalCount++;
                executionOrder.Add($"N{normalCount}");
            };

            EventBusEntity.EventHandler<TestGameStateEvent> lowHandler = (data) =>
            {
                lowCount++;
                executionOrder.Add($"L{lowCount}");
            };

            _eventBus.Subscribe(TestEventIds.TestMessage, highHandler);
            _eventBus.Subscribe(TestEventIds.TestPlayer, normalHandler);
            _eventBus.Subscribe(TestEventIds.TestGameState, lowHandler);

            // 混合发布不同优先级的事件
            for (int i = 0; i < 100; i++)
            {
                _eventBus.Publish(TestEventIds.TestMessage, new TestMessageEvent($"High {i}"), EventPriority.High);
            }
            for (int i = 0; i < 500; i++)
            {
                _eventBus.Publish(TestEventIds.TestPlayer, new TestPlayerEvent(0, Vector3.zero, "test"), EventPriority.Normal);
            }
            for (int i = 0; i < 1000; i++)
            {
                _eventBus.Publish(TestEventIds.TestGameState, new TestGameStateEvent("test", 0), EventPriority.Low);
            }

            yield return new WaitForSeconds(3f);

            // 验证优先级顺序
            Debug.Log($"High事件处理: {highCount}/100");
            Debug.Log($"Normal事件处理: {normalCount}/500");
            Debug.Log($"Low事件处理: {lowCount}/1000");
            Debug.Log($"前10个执行顺序: {string.Join(", ", executionOrder.Take(10))}");

            _eventBus.Unsubscribe(TestEventIds.TestMessage, highHandler);
            _eventBus.Unsubscribe(TestEventIds.TestPlayer, normalHandler);
            _eventBus.Unsubscribe(TestEventIds.TestGameState, lowHandler);
        }

        /// <summary>
        /// 持续压力测试
        /// </summary>
        private IEnumerator TestContinuousStress()
        {
            Debug.Log("\n=== 持续压力测试（10秒）===");

            int processedCount = 0;
            EventBusEntity.EventHandler<TestMessageEvent> handler = (data) => processedCount++;
            _eventBus.Subscribe(TestEventIds.TestMessage, handler);

            float startTime = Time.time;
            int frameCount = 0;
            float totalFrameTime = 0f;

            while (Time.time - startTime < 10f)
            {
                float frameStartTime = Time.realtimeSinceStartup;

                // 每帧发布50个事件
                for (int i = 0; i < 50; i++)
                {
                    _eventBus.Publish(
                        TestEventIds.TestMessage,
                        new TestMessageEvent($"Continuous {i}"),
                        (EventPriority)((i % 3) + 1)
                    );
                }

                frameCount++;
                totalFrameTime += Time.realtimeSinceStartup - frameStartTime;

                // 每秒输出一次状态
                if (frameCount % 60 == 0)
                {
                    Debug.Log($"时间: {Time.time - startTime:F1}s | 队列: {_eventBus.GetQueueCount()} | 已处理: {processedCount} | FPS: {1f / Time.deltaTime:F1}");
                }

                yield return null;
            }

            Debug.Log($"总帧数: {frameCount}");
            Debug.Log($"平均帧耗时: {(totalFrameTime / frameCount * 1000):F2} ms");
            Debug.Log($"总处理事件: {processedCount}");

            _eventBus.Unsubscribe(TestEventIds.TestMessage, handler);
        }

        /// <summary>
        /// 并发订阅测试
        /// </summary>
        private IEnumerator TestConcurrentSubscribers()
        {
            Debug.Log("\n=== 并发订阅测试（100个监听器）===");

            int callCount = 0;
            var handlers = new List<EventBusEntity.EventHandler<TestMessageEvent>>();

            // 创建100个监听器
            for (int i = 0; i < 100; i++)
            {
                EventBusEntity.EventHandler<TestMessageEvent> handler = (data) => callCount++;
                handlers.Add(handler);
                _eventBus.Subscribe(TestEventIds.TestMessage, handler);
            }

            var monitor = new PerformanceMonitor();
            monitor.Start();

            // 发布1000个事件
            for (int i = 0; i < 1000; i++)
            {
                _eventBus.Publish(
                    TestEventIds.TestMessage,
                    new TestMessageEvent($"Concurrent {i}"),
                    EventPriority.High
                );
            }

            yield return new WaitForSeconds(2f);

            monitor.EventsPublished = 1000;
            monitor.EventsProcessed = callCount;
            monitor.End();
            monitor.PrintResults();

            Debug.Log($"期望调用次数: {1000 * 100} = 100,000");
            Debug.Log($"实际调用次数: {callCount}");

            // 清理
            foreach (var handler in handlers)
            {
                _eventBus.Unsubscribe(TestEventIds.TestMessage, handler);
            }
        }

        #endregion
    }
}
